package com.mnjpcorp.shopping.security;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl;

/**
 * Extends the baseline Spring Security JdbcDaoImpl and implements change password functionality.
 * 
 * Used in Chapter 4 example of customizing JdbcDaoImpl.
 * 
 * @author nhn
 */
public class CustomJdbcDaoImpl extends JdbcDaoImpl implements IChangePassword {
	@Autowired
	private PasswordEncoder passwordEncoder;

	public void changePassword(String username, String password) {
		SaltedUser user = (SaltedUser)loadUserByUsername(username);
		System.out.println("salt : " + user.getSalt());
		String encodedPassword = passwordEncoder.encodePassword(password, user.getSalt());
		getJdbcTemplate().update("UPDATE tbl_users SET user_password = ? WHERE user_id = ?", encodedPassword, username);
		//		getJdbcTemplate().update("UPDATE tbl_users SET user_password = ? WHERE user_id = ?", password, username);
	}

	@Override
	protected UserDetails createUserDetails(String username, UserDetails userFromUserQuery, List<GrantedAuthority> combinedAuthorities) {
		String returnUsername = userFromUserQuery.getUsername();
		if (!isUsernameBasedPrimaryKey()) {
			returnUsername = username;
		}
		System.out.println(userFromUserQuery.getPassword());
		return new SaltedUser(returnUsername, userFromUserQuery.getPassword(), userFromUserQuery.isEnabled(), true, true, true, combinedAuthorities, ((SaltedUser)userFromUserQuery).getSalt());
	}

	@Override
	public List<UserDetails> loadUsersByUsername(String username) throws UsernameNotFoundException, DataAccessException {
		return getJdbcTemplate().query(getUsersByUsernameQuery(), new String[] {username}, new RowMapper<UserDetails>() {
			@Override
			public UserDetails mapRow(ResultSet rs, int rowNum) throws SQLException {
				String username = rs.getString(1);
				String password = rs.getString(2);
				Long salt = rs.getDate(3).getTime();
				System.out.println("salt : " + salt);

				return new SaltedUser(username, password, true, true, true, true, AuthorityUtils.NO_AUTHORITIES, salt);
			}
		});
	}
}
